package main

import (
	"fmt"
	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
	"github.com/yagochat-server/grapinter/utils"
	"log"
	"regexp"
	"strings"
	"time"
)

var (
	//device      string = "en0"
	snapshotLen int32 = 1024
	promiscuous bool  = false
	err         error
	timeout     time.Duration = 30 * time.Second
	//handle      *pcap.Handle
)

func worker(device string, c chan int) {

	var handle *pcap.Handle
	// 从channel接收数据，如果channel没有数据可接收，当前goroutine会阻塞
	data := <-c
	fmt.Println("Worker device", device, "data:", data)

	handle, err = pcap.OpenLive(device, snapshotLen, true, timeout)
	if err != nil {
		log.Fatal(err)
	}
	defer handle.Close()
	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

	for packetMsg := range packetSource.Packets() {

		printPacketInfo(packetMsg)
	}
	time.Sleep(time.Second) // 模拟工作
	//}
}

func main() {
	c := make(chan int)
	var device map[int]string
	device = make(map[int]string, 2)
	device[0] = "en0"
	device[1] = "en1"
	worker(device[0], c)
	worker(device[1], c)
	//handle, err = pcap.OpenLive(device, snapshotLen, true, timeout)
	//if err != nil {
	//	log.Fatal(err)
	//	return
	//}
	//defer handle.Close()
	//
	//packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	//
	//for packetMsg := range packetSource.Packets() {
	//
	//	go printPacketInfo(packetMsg)
	//}
}

func getSNI(data []byte) string {
	return utils.GetServerExtensionName(data[5:])
}

func printPacketInfo(packet gopacket.Packet) {
	if err := packet.ErrorLayer(); err != nil {
		fmt.Println("解码错误,错误原因:", err)
	}
	//处理Tls
	tlsLayer := packet.Layer(layers.LayerTypeTLS)
	if tlsLayer != nil {
		fmt.Println("TLS 数据处理:")
		tls := &layers.TLS{}
		parser := gopacket.NewDecodingLayerParser(layers.LayerTypeTLS, tls)
		var decodedLayers []gopacket.LayerType

		err := parser.DecodeLayers(packet.Data(), &decodedLayers)
		if err != nil {
			fmt.Println("解码错误,错误原因:", err)
			return
		}

		for _, hs := range tls.Handshake {
			fmt.Println("Tls content type ", hs.ContentType)
			handShakeType := packet.Data()[5]
			var sni string

			switch handShakeType {
			case 0x01:
				sni = getSNI(packet.Data())
				fmt.Println("Tls sni :", sni)
			}
			//break
		}

	}
	//
	////处理dns数据
	dnsLayer := packet.Layer(layers.LayerTypeDNS)
	if dnsLayer != nil {
		dnsPacket, _ := dnsLayer.(*layers.DNS)
		fmt.Println("dns数据处理:")
		fmt.Println("dns请求地址:", string(dnsPacket.Questions[0].Name))
		for _, v := range dnsPacket.Answers {

			fmt.Println("dns返回地址:", v.String())
		}
	}

	////处理http信息
	////// 判断数据包是否为TCP数据包，可解析源端口、目的端口、seq序列号、tcp标志位等
	tcpLayer := packet.Layer(layers.LayerTypeTCP)
	if tcpLayer != nil {
		tcp, _ := tcpLayer.(*layers.TCP)
		applicationLayer := packet.ApplicationLayer()
		if applicationLayer != nil {
			payload := string(applicationLayer.Payload())

			//fmt.Println(payload)
			if strings.HasPrefix(payload, "GET") || strings.HasPrefix(payload, "POST") {
				fmt.Println("HTTP 数据处理:")

				fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort)
				fmt.Println("Sequence number: ", tcp.Seq)

				reg := regexp.MustCompile(`(?s)(GET|POST) (.*?) HTTP.*Host: (.*?)\n`)
				if reg != nil {
					//提取关键信息
					result := reg.FindStringSubmatch(payload)
					fmt.Println(result)
					if len(result) == 4 {
						strings.TrimSpace(result[2])
						url := "http://" + strings.TrimSpace(result[3]) + strings.TrimSpace(result[2])
						fmt.Println("url:", url)
						fmt.Println("host:", result[3])
					}
				}

			}

		}
	}

	time.Sleep(time.Millisecond * 100)

}
